﻿using System;
using System.Collections.Generic;
using System.Text;
using APIMonLib;

namespace CPN {
    [Serializable]
    public class Token : TransferUnit, PrefixPrintable {
		//Contains reference to the place where token is stored
        private Place _place = null;

		/// <summary>
		/// Returns reference to place where token is stored
		/// </summary>
        public Place place {
            get {
                return _place;
            }
        }

        public Token() {
        }

		/// <summary>
		/// Creates token by copying fields from transfer unit
		/// </summary>
		/// <param name="tu">tranfer unit to copy fields from</param>
        public Token(TransferUnit tu)
            : base(tu) {
        }

		/// <summary>
		/// Creates new token and copies only fields provided in keys_to_copy array
		/// </summary>
		/// <param name="t">token to copy from</param>
		/// <param name="keys_to_copy">keys to copy into new token</param>
        public Token(Token t, String[] keys_to_copy)
            : this() {
            this.loadFields(keys_to_copy, "old", t);
        }

        /// <summary>
        /// This method installs current place for this token
        /// </summary>
        /// <param name="place"></param>
        public void setCurrentPlace(Place place) {
            this._place = place;
        }

		/// <summary>
		/// Lays out contents of token into string for future printing.
		/// The Prefix is added to the beginning of each line
		/// </summary>
		/// <param name="prefix"></param>
		/// <returns></returns>
        public string toString(string prefix) {
            String result = "Token:";
            String expander = "    ";
            prefix += expander + "|";
            foreach (String key in this.getFields()) {
                if (this[key] is PrefixPrintable) {
                    result += "\n" + prefix + "---" + key + " =\n" + prefix + expander + ((PrefixPrintable)this[key]).toString(prefix);
                } else {
                    result += "\n" + prefix + "---" + key + " = " + this[key];
                }
            }
            return result;
        }

		/// <summary>
		/// Standard field name for previous tuple in token hierarchy
		/// </summary>
        private const string PREV = "prev";

		/// <summary>
		/// Standart field for storing previous tuple into token.
		/// </summary>
        public Tuple prevTuple {
            get {
               return (Tuple)this[PREV];
            }
            set {
                this[PREV]=value;
            }
        }

        public override string ToString() {
            return toString("%");
        }
    }
}